/**
 * Created by rockyren on 14-8-27.
 */

/**
 * @class 多边形生成管理类
 */

define(function(require,exports,module){
  var cfg = require("./config");
  var Point = require("./base-modules/Point");
  var CanvasAreas = require("./base-modules/CanvasAreas");

  /**
   *
   * @constructor 多边形管理类构造器
   */
  function PolygonsHandle() {
    //多边形数目,@test随机生成10-20个
    //this.num = Math.floor(Math.random()*10) + 10;
    this.num = Math.floor(Math.random() * cfg.POLYGON_NUM_BASE) + cfg.POLYGON_NUM_EXTRA;
    //多边形数组
    this.Polygons = new Array();
    //初始化num个多边形
    for(var i=0;i<this.num;i++) {

      this.Polygons[i] = new Polygon(i);
    }
    //多边形面积数组
    this.proportions= new Array();
  }

  module.exports = PolygonsHandle;

  /**
   * @method 根据num值画num个多边形
   */
  PolygonsHandle.prototype.drawPolygons = function() {
    for(var i=0;i<this.num;i++) {
      //如果凸包点少于2个,重新生成一个新的多边形
      while(!this.Polygons[i].drawPolygon()){
        this.Polygons[i] = new Polygon(i);
      }
    }
  };

  /**
   * @method 获得所有多边形的面积数组
   * @returns {Array|*} 多边形面积数组
   */
  PolygonsHandle.prototype.getProportions = function() {
    for(var i=0 ; i<this.num ; i++) {
      this.proportions[i] = this.Polygons[i].proportion;
    }
    return this.proportions;
  };

  /**
   * @innerClass 多边形类,内部类
   */
  function Polygon(id) {
    //标识多边形
    this.id = id;
    //:凸点数组
    this.outers = new Array();
    //随机生成3-41个点
    this.n = Math.floor(Math.random()* 38) +3;
    //所有点数组
    this.points = new Array();
    //多边形面积
    this.proportion = 0;


    //生成点的范围
    var canvasAreas = new CanvasAreas();
    var id_area = canvasAreas.getArea(id);
    var x_begin = id_area.x + 1;
    var x_width = id_area.width -1;
    var y_begin = id_area.y + 1;
    var y_height = id_area.height - 1;

    for(var i=0;i<this.n;i++) {
      this.points[i] = new Point(Math.floor(Math.random() * x_width) + x_begin ,
          Math.floor(Math.random() * y_height) + y_begin  )	;
    }

  }

  /**
   * @method 凸包画多边形
   * @return {bool} 如果凸包点少于2个,则返回false
   */
  Polygon.prototype.drawPolygon = function(){
    //凸包排序
    //@wait:消除重复点
    this.points.sort(function(p1,p2){
      if(p1.y > p2.y || (p1.y == p2.y && p1.x>p2.x)) {
        return 1;
      }
      else {
        return -1;
      }

    });



    //初始化第一条边
    this.outers[0] = this.points[0];
    this.outers[1] = this.points[1];
    //转折点下标
    var turn = 1;

    //计算凸包点
    for(var i=2;i<this.points.length;i++)
    {
      while(turn && !this._ral(this.outers[turn],this.outers[turn-1],this.points[i])) {
        turn--;
      }
      turn++;
      this.outers[turn] = this.points[i];
    }

    //如果生成的凸包点少于3个,则返回false
    if(this.outers.length<3) {return false;}
    //计算面积
    this.proportion = this._calPolygonPro(this.outers);



    //画图
    cfg.CTX.strokeStyle = cfg.boundaryColor;
    for(var i=0;i<this.outers.length;i++) {
      if(i == 0) {
        cfg.CTX.moveTo(this.outers[i].x,this.outers[i].y);
      }
      else {
        cfg.CTX.lineTo(this.outers[i].x,this.outers[i].y);
      }

    }
    cfg.CTX.closePath();
    cfg.CTX.stroke();

    return true;

  }


  /**
   * @method 用叉乘判断点是否加入凸包点
   * @param p1
   * @param p2
   * @param p3
   * @returns {boolean}
   * @private
   */
  Polygon.prototype._ral = function(p1,p2,p3) {
    return 	((p2.x - p1.x) * (p3.y - p1.y) > (p3.x - p1.x) * (p2.y - p1.y));
  };

  /**
   * @method 由三个点坐标计算三角形面积
   * @param p1 点1
   * @param p2 点2
   * @param p3 点3
   * @returns {number} 返回面积
   * @private
   */
  Polygon.prototype._calTrianglePro = function(p1,p2,p3) {
    return 0.5 * ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
  };

  /**
   * @method 由凸包点集计算多边形面积
   * @param points 多边形点集
   * @returns {number} 返回面积
   * @private
   */
  Polygon.prototype._calPolygonPro =  function(points) {
    if(points.length <= 2) {
      console.log("多边形点个数少于3个");
      return 0;
    }
    p0 = new Point(points[0].x,points[0].y);
    var proportion = 0;
    for(var i=0;i<points.length-2;i++) {
      proportion += this._calTrianglePro(p0,points[i+1],points[i+2]);
    }

    return proportion>0 ? proportion : -proportion;
  }
});